package cn.imvc.app.models;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.puff.cache.redis.Redis;

import cn.imvc.app.domains.PageDomain;
import cn.imvc.app.entities.Brand;
import cn.imvc.app.entities.GoodsClass;
import cn.imvc.app.repositories.GoodsClassRepository;
import cn.imvc.core.ICache;
import cn.imvc.util.ToolUtils;

@Service
public class GoodsClassModelImpl implements GoodsClassModel {
	@Resource
	private GoodsClassRepository goodsClassRepository;
	@Autowired
	private CommonModel commonModel;
	@Autowired
	private BrandModel brandModel;
	
	
	@Autowired
	ICache cache;

	@Override
	public List<GoodsClass> findTopLevelClass() {
		PageDomain<GoodsClass> domain = null;
		List<GoodsClass> list = null;
		String key = "goodsClassList";
		int minute = ToolUtils.getMinute(new Date());
		while (true) {
			domain = cache.get("DATA", key);
			if (domain == null) {
				if (Redis.getInstance().setnx(key + minute, "aa") == 1) {
					Redis.getInstance().expire(key + minute, 20);
					list = goodsClassRepository.findByParentIdIsNull();
					domain = new PageDomain<GoodsClass>();
					domain.setListResult(list);
					cache.put("DATA", key, domain, 3600);
					Redis.getInstance().remove(key + minute);
					return list;
				} else {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			} else {
				list = domain.getListResult();
				break;
			}
		}
		return list;
	}

	@Override
	public List<GoodsClass> findByParentId(Integer parentId) {
		return goodsClassRepository.findByParentIdAndIsShow(parentId,(byte)1);
	}

	@Override
	public List<GoodsClass> findAll() {
		return goodsClassRepository.findAll();
	}

	@Override
	public GoodsClass findById(Integer id) {
		//Integer goodsClassMaxId = cache.getSecond("MAX_ID", "goodsClass");
		Integer goodsClassMaxId = commonModel.findMaxId("goodsClass");
		if (id > goodsClassMaxId) {
			return null;
		}
		GoodsClass goodsClass = null;
		String key = "goodsClass";
		int minute = ToolUtils.getMinute(new Date());
		while (true) {
			goodsClass = cache.get("DATA", key);
			if (goodsClass == null) {
				if (Redis.getInstance().setnx(key + minute, "aa") == 1) {
					Redis.getInstance().expire(key + minute, 20);
					goodsClass = goodsClassRepository.getOne(id);
					cache.put("DATA", key, goodsClass, 1800);
					Redis.getInstance().remove(key + minute);
					return goodsClass;
				} else {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			} else {
				return goodsClass;
			}
		}
	}

	public List<Object[]> findMaxId() {
		return goodsClassRepository.findAllSql("select max(id) from goods_class");
	}

	public Map<String, Object> findAllWithGroup() {
		PageDomain<GoodsClass> domain = null;
		Map<String, Object> resultMap = null;
		String key = "goodsClassMap";
		int minute = ToolUtils.getMinute(new Date());
		//cache.remove("DATA", key);
		while (true) {
			domain = cache.get("DATA", key);
			if (domain == null) {
				if (Redis.getInstance().setnx(key + minute, "aa") == 1) {
					Redis.getInstance().expire(key + minute, 20);
//					List<GoodsClass> list = goodsClassRepository.findByIsShow((byte)1);
					List<GoodsClass> list = goodsClassRepository.findByIsShowOrderBySort((byte)1);
					Map<String, List<GoodsClass>> goodsClassesGroupByparentId = list.stream().collect(Collectors.groupingBy(goodsClass -> {
						GoodsClass parent = goodsClass.getParent();
						return "parentId" + (parent == null ? 0 : parent.getId());
					}));
					for (Map.Entry<String, List<GoodsClass>> groupedList : goodsClassesGroupByparentId.entrySet()) {
						groupedList.getValue().sort((a, b) -> {
							if(a.getSort()==null){
								return 1;
							}
							if(b.getSort()==null){
								return -1;
							}
							return a.getSort() - b.getSort();
						});
					}
					domain = new PageDomain<GoodsClass>();
					resultMap = new HashMap<String, Object>();
					resultMap.put("resultMap", goodsClassesGroupByparentId);
					
//					if (goodsClassesGroupByparentId != null && goodsClassesGroupByparentId.get("parentId0") != null) {
//						List<GoodsClass> temList = goodsClassesGroupByparentId.get("parentId0");
//						if (temList != null && temList.size() > 0)
//							resultMap.put("selectedClassId", goodsClassesGroupByparentId.get("parentId0").get(0).getId());
//					}
					resultMap.put("selectedClassId", "-1");
					//查询品牌列表
					List<Brand> brandList = brandModel.getAllBrand();
					resultMap.put("brandList", brandList);
					/*List<BrandGoodsClass> brandGoodsClassList = brandModel.getAllBrandGoodsClass();
					if(brandGoodsClassList!=null&&brandGoodsClassList.size()>0){
						Map<String,List<Brand>> groupedBrand = new HashMap<String,List<Brand>>();
						for (BrandGoodsClass brandGoodsClass : brandGoodsClassList) {
							String temKey = "goodsClassId"+brandGoodsClass.getGoodsClass().getId();
							List<Brand> temList = groupedBrand.get(temKey);
							if(temList==null){
								temList = new ArrayList<>();
								groupedBrand.put(temKey, temList);
							}
							temList.add(brandGoodsClass.getBrand());
						}
						resultMap.put("groupedBrand", groupedBrand);
						//Map<String,List<BrandGoodsClass>> groupedBrandGoodsClassList =brandGoodsClassList.stream().collect(Collectors.groupingBy(brandGoodsClass->"goodsClassId"+brandGoodsClass.getGoodsClass().getId()));
						//resultMap.put("groupedBrandGoodsClassList", groupedBrandGoodsClassList);
					}*/
					domain.setMapResult(resultMap);
					cache.put("DATA", key, domain, 3600);
					Redis.getInstance().remove(key + minute);
					break;
				} else {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			} else {
				resultMap = domain.getMapResult();
				break;
			}
		}
		return resultMap;
	}
}
